home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Note: Return true if value loaded, false if not;
- */
- heir13(lval) int lval[]; {
- int k;
- char *ptr;
- if (match("++")) { /* ++lval */
- if(heir13(lval)==0) {
- needlval();
- return 0;
- }
- step(inc, lval);
- return 0;
- }
- else if (match("--")) { /* --lval */
- if(heir13(lval)==0) {
- needlval();
- return 0;
- }
- step(dec, lval);
- return 0;
- }
- else if (match("~")) { /* ~ */
- if(heir13(lval)) rvalue(lval);
- com();
- lval[4] = ~lval[4];
- return 0;
- }
- else if (match("!")) { /* ! */
- if(heir13(lval)) rvalue(lval);
- lneg();
- lval[4] = !lval[4];
- return 0;
- }
- else if (match("-")) { /* unary - */
- if(heir13(lval)) rvalue(lval);
- neg();
- lval[4] = -lval[4];
- return 0;
- }
- else if (match("*")) { /* unary * */
- if(heir13(lval)) rvalue(lval);
- if(ptr=lval[0]) lval[1]=ptr[TYPE];
- else lval[1]=CINT;
- lval[2]=0; /* flag as not pointer or array */
- lval[3]=0; /* flag as not constant */
- return 1;
- }
- else if (match("&")) { /* unary & */
- if(heir13(lval)==0) {
- error("illegal address");
- return 0;
- }
- ptr=lval[0];
- lval[2]=ptr[TYPE];
- if(lval[1]) return 0;
- /* global & non-array */
- address(ptr);
- lval[1]=ptr[TYPE];
- return 0;
- }
- else if (match("(int)")) { /* (int) cast */
- if(heir13(lval)) rvalue(lval);
- lval[0]=castint;
- lval[1]=CINT;
- lval[2]=0;
- return 0;
- }
- else if (match("(char)")) { /* (char) cast */
- if(heir13(lval)) rvalue(lval);
- lval[0]=castchar;
- lval[1]=CCHAR;
- lval[2]=0;
- return 0;
- }
- else if (match("(int *)")) { /* (int *) cast */
- if(heir13(lval)) rvalue(lval);
- lval[0]=castpint;
- lval[1]=0;
- lval[2]=CINT;
- return 0;
- }
- else if (match("(char *)")) { /* (char *) cast */
- if(heir13(lval)) rvalue(lval);
- lval[0]=castpchar;
- lval[1]=0;
- lval[2]=CCHAR;
- return 0;
- }
- else {
- k=heir14(lval);
- if(match("++")) { /* lval++ */
- if(k==0) {
- needlval();
- return 0;
- }
- step(inc, lval);
- dec(lval[2]>>2);
- return 0;
- }
- else if(match("--")) { /* lval-- */
- if(k==0) {
- needlval();
- return 0;
- }
- step(dec, lval);
- inc(lval[2]>>2);
- return 0;
- }
- else return k;
- }
- }
-
- heir14(lval) int *lval; {
- int k, const, val, lval2[8];
- char *ptr, *before, *start;
- k=primary(lval);
- ptr=lval[0];
- blanks();
- if((ch=='[')|(ch=='(')) {
- lval[5]=1; /* secondary register will be used */
- while(1) {
- if(match("[")) { /* [subscript] */
- if(ptr==0) {
- error("can't subscript");
- junk();
- needtoken("]");
- return 0;
- }
- else if(ptr[IDENT]==POINTER) rvalue(lval);
- else if(ptr[IDENT]!=ARRAY) {
- error("can't subscript");
- k=0;
- }
- setstage(&before, &start);
- lval2[3]=0;
- plunge2(0, 0, heir1, lval2, lval2); /* lval2 deadend */
- needtoken("]");
- /* -- beginning of new code -- */
- if(match("[")) { /* we have more dimensions */
- if(ptr[NDIM] < 2 ) {
- error("too many dimension"); /* variable declared with */
- junk(); /* less dimensions */
- needtoken("]");
- return 0;
- }
- if(lval2[3]) { /* Test for index being constant */
- clearstage(before, 0); /* ignore code generated by plunge2 */
- ol("XCHG AX,BX");
- /* const(lval2[4]); */
- ot("MOV AX,");
- outdec(lval2[4]);
- nl();
- }
- ol("PUSH BX");
- if((lval2[3] == 0) | lval2[4]) {
- if(ptr[TYPE] == CINT) /* Get 2nd dimension size */
- const2(ptr[CDIM] << LBPW); /* and adjust for type size */
- else
- const2(ptr[CDIM]);
- mult(); /* AX gets C * i1 */
- }
- setstage(&before, &start);
- lval2[3] = 0; /* parse subscript 2 expression */
- plunge2(0, 0, heir1, lval2, lval2);
- needtoken("]");
- if(lval2[3]) { /* if index is a constant */
- clearstage(before, 0); /* dump plunge2 generated code */
- if(lval2[4]) /* if index is non-zero */
- if(ptr[TYPE] == CINT) {
- ot("ADD AX,");
- outdec(lval2[4] << LBPW);
- nl();
- }
- else {
- ot("ADD AX,");
- outdec(lval2[4]);
- }
- }
- else {
- if(ptr[TYPE] == CINT)
- doublereg();
- add(); /* AX gets C*i1 + i2 */
- }
- ol("POP BX");
- /* retrieve array base from stack */
- add(); /* calculate segment address of target */
- }
- else { /* only one dimension */
- /* -- end of new code -- */
- if(lval2[3]) {
- clearstage(before,0);
- if(lval2[4]) {
- if(ptr[TYPE]==CINT) const2(lval2[4]<<LBPW);
- else const2(lval2[4]);
- add();
- }
- }
- else {
- if(ptr[TYPE]==CINT) doublereg();
- add();
- }
- }
- lval[0]=lval[2]=0;
- lval[1]=ptr[TYPE];
- k=1;
- }
- else if(match("(")) { /* function(...) */
- if(ptr==0) callfunction(0); /* call to an absolute address */
- else if(ptr[IDENT]!=FUNCTION) {
- rvalue(lval);
- callfunction(0);
- }
- else callfunction(ptr);
- k=lval[0]=lval[3]=0;
- }
- else return k;
- }
- }
- if(ptr==0) return k; /* if constant, return */
- if(ptr[IDENT]==FUNCTION) { /* if function name without "()", gen address */
- address(ptr);
- return 0;
- }
- return k;
- }
-
- /*
- ** fixed per A. Macpherson letter, DDJ #81
- */
- primary(lval) int *lval; {
- char *ptr;
- int k;
- if(match("(")) { /* (expression) */
- do
- k=heir1(lval);
- while(match(",")); /* comma operator */
- needtoken(")");
- return k;
- }
- putint(0, lval, 8<<LBPW); /* clear lval array */
- if(symname(ssname, YES)) {
- if(ptr=findloc(ssname)) {
- #ifdef STGOTO
- if(ptr[IDENT]==LABEL) {
- experr();
- return 0;
- }
- #endif
- ptr[STATUS] |= USED;
- getloc(ptr);
- lval[0]=ptr;
- lval[1]=ptr[TYPE];
- if(ptr[IDENT]==POINTER) {
- lval[1]=CINT;
- lval[2]=ptr[TYPE];
- }
- if(ptr[IDENT]==ARRAY) {
- lval[2]=ptr[TYPE];
- return 0;
- }
- else return 1;
- }
- if(ptr=findglb(ssname)) {
- ptr[STATUS] |= USED;
- if(ptr[IDENT]!=FUNCTION) {
- lval[0]=ptr;
- lval[1]=0;
- if(ptr[IDENT]!=ARRAY) {
- if(ptr[IDENT]==POINTER) lval[2]=ptr[TYPE];
- return 1;
- }
- address(ptr);
- lval[1]=lval[2]=ptr[TYPE];
- return 0;
- }
- }
- /* implicitly define (if necessary) */
- ptr=addsym(ssname, FUNCTION, CINT, 0, &glbptr, STATIC, 0, 0);
- ptr[STATUS] |= USED;
- lval[0]=ptr;
- lval[1]=0;
- return 0;
- }
- if(constant(lval)==0) experr();
- return 0;
- }
-
- experr() {
- error("invalid expression");
- const(0);
- junk();
- }
-
- callfunction(ptr) char *ptr; { /* symbol table entry or 0 */
- int nargs, const, val;
- nargs=0;
- blanks(); /* already saw open paren */
- if(ptr==0) push(); /* calling AX */
- while(streq(lptr,")")==0) {
- if(endst()) break;
- expression(&const, &val);
- if(ptr==0) swapstk(); /* don't push addr */
- push(); /* push argument */
- nargs=nargs+BPW; /* count args*BPW */
- if (match(",")==0) break;
- }
- needtoken(")");
- if(streq(ptr+NAME, "CCARGC")==0) loadargc(nargs>>LBPW);
- if(ptr) call(ptr+NAME);
- else callstk();
- csp=modstk(csp+nargs);
- }
-
-